package com.junzhiit.nengji.shop.web.util.printing.service.impl;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bainaeco.framework.util.DateUtil;
import com.junzhiit.nengji.bo.MemberCardUseBO;
import com.junzhiit.nengji.bo.OrdersGoodsBO;
import com.junzhiit.nengji.bo.OrdersPrintingBO;
import com.junzhiit.nengji.dao.MemberCardUseDAO;
import com.junzhiit.nengji.dao.OrdersDAO;
import com.junzhiit.nengji.dao.OrdersGoodsDAO;
import com.junzhiit.nengji.dao.PrinterDAO;
import com.junzhiit.nengji.dao.PrinterTemplateDAO;
import com.junzhiit.nengji.dao.cache.PrinterCacheDAO;
import com.junzhiit.nengji.dao.util.DIYKey;
import com.junzhiit.nengji.model.Printer;
import com.junzhiit.nengji.model.PrinterTemplate;
import com.junzhiit.nengji.model.enums.OrderType;
import com.junzhiit.nengji.model.enums.PayWay;
import com.junzhiit.nengji.shop.service.impl.BaseServiceImpl;
import com.junzhiit.nengji.shop.web.exception.OrdersNotFoundException;
import com.junzhiit.nengji.shop.web.exception.PrintingException;
import com.junzhiit.nengji.shop.web.util.OrderNumberUtils;
import com.junzhiit.nengji.shop.web.util.printing.PrintingUtil;
import com.junzhiit.nengji.shop.web.util.printing.enums.ResultErrorStatus;
import com.junzhiit.nengji.shop.web.util.printing.service.PrintingUtilService;

@Service
public class PrintingUtilServiceImpl extends BaseServiceImpl implements PrintingUtilService {

	@Autowired
	private PrinterDAO printerDAO;

	@Autowired
	private PrinterTemplateDAO printerTemplateDAO;

	@Autowired
	private PrinterCacheDAO printerCacheDAO;

	@Autowired
	private OrdersDAO ordersDAO;

	@Autowired
	private OrdersGoodsDAO ordersGoodsDAO;
	
	@Autowired
	private MemberCardUseDAO memberCardUseDAO;

	@Value("${printer.client.id}")
	private String clientId;

	@Value("${printer.client.secret}")
	private String clientSecret;

	@Override
	public void oauthOauth() {
		String key = DIYKey.getPrinterAccessTokenKey();
		String configure = printerCacheDAO.getString(key);
		if (StringUtils.isNotBlank(configure)) {
			JSONObject json = (JSONObject) JSON.parse(configure);
			JSONObject result = PrintingUtil.oauthOauth(clientId, clientSecret, json.get("refreshToken").toString());
			int errorCode = Integer.parseInt(result.get("error").toString());
			if (errorCode != ResultErrorStatus.SUCCESS.toIntStatus()) {
				JSONObject news = new JSONObject();
				result = PrintingUtil.oauthOauth(clientId, clientSecret);
				errorCode = Integer.parseInt(result.get("error").toString());
				if (errorCode != ResultErrorStatus.SUCCESS.toIntStatus()) {
					throw new PrintingException(result.get("error_description").toString());
				}
				JSONObject body = result.getJSONObject("body");
				news.put("time", PrintingUtil.getTimestamp());
				news.put("accessToken", body.get("access_token").toString());
				news.put("refreshToken", body.get("refresh_token").toString());
				printerCacheDAO.addString(key, news.toJSONString());
			}
		} else {
			JSONObject news = new JSONObject();
			JSONObject result = PrintingUtil.oauthOauth(clientId, clientSecret);
			int errorCode = Integer.parseInt(result.get("error").toString());
			if (errorCode != ResultErrorStatus.SUCCESS.toIntStatus()) {
				throw new PrintingException(result.get("error_description").toString());
			}
			JSONObject body = result.getJSONObject("body");
			news.put("time", PrintingUtil.getTimestamp());
			news.put("accessToken", body.get("access_token").toString());
			news.put("refreshToken", body.get("refresh_token").toString());
			printerCacheDAO.addString(key, news.toJSONString());
		}
	}

	@Override
	public void printIndex(String shopId, String orderId) {
		String key = DIYKey.getPrinterAccessTokenKey();
		String dailyOrderNumberKey = DIYKey.getDailyOrderNumber();
		String configure = printerCacheDAO.getString(key);
		String dailyOrderNumber = printerCacheDAO.getString(dailyOrderNumberKey);

		dailyOrderNumber = OrderNumberUtils.cardNumber(dailyOrderNumber, 1);

		printerCacheDAO.addString(dailyOrderNumberKey, dailyOrderNumber);

		JSONObject json = (JSONObject) JSON.parse(configure);
		OrdersPrintingBO ordersBO = ordersDAO.findOrderIdToPrinting(orderId);
		if (ordersBO == null) {
			throw new OrdersNotFoundException("没找到订单");
		}
		Double  memberCardUseCouponsMoney = new Double(0);
		List<MemberCardUseBO> memberCardUseList = memberCardUseDAO.getAllByOrderNumber(ordersBO.getId());
		for(MemberCardUseBO ubo: memberCardUseList){
			memberCardUseCouponsMoney += ubo.getPrivilegeMoney();
		}
		List<OrdersGoodsBO> ordersGoodsBOList = ordersGoodsDAO.getOrderGoods(orderId);
		List<Printer> printerList = printerDAO.getPrinterByShopId(shopId,ordersBO.getType());
		for (Printer printer : printerList) {
			if (ordersBO.getType() == printer.getType()) {
				PrinterTemplate printerTemplate = printerTemplateDAO.query(printer.getPrinterTemplateId());
				String content = printerTemplate.getContent();

				int start = content.indexOf("table");
				int end = content.lastIndexOf("table");
				String son = null;
				if (start != -1 && end != -1) {
					son = content.substring(start - 1, end + 6);
				}
				if (StringUtils.isNotBlank(son)) {
					StringBuffer con = new StringBuffer("<table>");
					String head = son.replace("<table>", "");
					head = head.replace("</table>", "");
					con.append(head);
					for (int i = 0, t = ordersGoodsBOList.size(); i < t; i++) {
						OrdersGoodsBO bo = ordersGoodsBOList.get(i);
						con.append("<tr>");
						if(StringUtils.isNotBlank(bo.getStandard())){
							con.append("<td>" + bo.getName()+"("+bo.getStandard()+")</td>");
						}else{
							con.append("<td>" + bo.getName()+"</td>");
						}
						con.append("<td>" + bo.getNumber() + "</td>");
						con.append("<td>" + bo.getPrice() + "</td>");
						con.append("</tr>");
					}
					con.append("</table>");
					content = content.replace(son, con.toString());
				}
				String tableNumber = ordersBO.getTableNumber() == null ? "" : ordersBO.getTableNumber();

				content = content.replace("type", OrderType.toType(ordersBO.getType()).toStringText());
				content = content.replace("code", tableNumber);
				
				content = content.replace("multiCouplet", printer.getNumber().toString());
				content = content.replace("dailyOrderNumber", dailyOrderNumber);
				content = content.replace("shopName", ordersBO.getShopName() == null ? "" : ordersBO.getShopName());
				content = content.replace("realMoney",  ordersBO.getRealMoney().toString());
				
				content = content.replace("foodBoxCharge",  ordersBO.getFoodBoxCharge().toString());
				
				content = content.replace("couponsMoney", ordersBO.getCouponsMoney().toString());
				content = content.replace("payMoney", ordersBO.getPayMoney().toString());
				content = content.replace("shopOrderNumber", ordersBO.getShopOrderNumber());
				content = content.replace("payWay", PayWay.toValue(ordersBO.getPayWay()).toStringText());
				String date = DateUtil.format(ordersBO.getPayTime(), DateUtil.DATETIME_PATTERN_DEFAULT);
				content = content.replace("payTime", date);
				content = content.replace("remark ", ordersBO.getRemark() == null ? "" : ordersBO.getRemark());
				
				if(OrderType.DELIVERY.toIntValue() == ordersBO.getType()){
					content = content.replace("postage", ordersBO.getPostage().toString());
				}else{
					content = content.replace("postage","");
				}
				
				if(memberCardUseList.size()<=0){
					content = content.replace("privilegeMoney", "0");
				}else{
					content = content.replace("privilegeMoney", memberCardUseCouponsMoney.toString());
				}
				
				
				if (OrderType.EXTRACT.toIntValue() == ordersBO.getType()) {
					content = content.replace("userName",
							ordersBO.getConsumeName() == null ? "" : ordersBO.getConsumeName());
					content = content.replace("userPhone",
							ordersBO.getConsumePhone() == null ? "" : ordersBO.getConsumePhone());
					content = content.replace("address","");
				} else {
					content = content.replace("userName", ordersBO.getUserName() == null ? "" : ordersBO.getUserName());
					content = content.replace("userPhone",
							ordersBO.getMobilePhone() == null ? "" : ordersBO.getMobilePhone());
					String address = (ordersBO.getArea()==null?"":ordersBO.getArea()) + (ordersBO.getAddress() == null ? "" : ordersBO.getAddress());
					
					content = content.replace("address",address);
				}

				String accessToken = "";
				if (json != null) {
					accessToken = json.get("accessToken").toString();
				}

				JSONObject result = PrintingUtil.printIndex(clientId, clientSecret, printer.getDeviceNumber(), orderId,
						accessToken, content);
				int errorCode = Integer.parseInt(result.get("error").toString());
				if (!StringUtils.isNotBlank(accessToken)
						|| errorCode == ResultErrorStatus.ACCESS_TOKEN_EXPIRED.toIntStatus()) {
					oauthOauth();
					printIndex(shopId, orderId);
					return;
				}
				if (errorCode != ResultErrorStatus.SUCCESS.toIntStatus()
						&& errorCode != ResultErrorStatus.ACCESS_TOKEN_EXPIRED.toIntStatus()) {
					throw new PrintingException(result.get("error_description").toString());
				}
			}

		}
	}

}
